home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ARASAN_S.ZIP / MOVEORD.CPP < prev    next >
C/C++ Source or Header  |  1994-04-27  |  4KB  |  160 lines

  1. // Copyright 1994 by Jon Dart.  All Rights Reserved.
  2.  
  3. #include "moveord.h"
  4. #include "scoring.h"
  5. #include "rmove.h"
  6. #include "constant.h"
  7. #include "attacke.h"
  8. #include "bearing.h"
  9. #include "util.h"
  10. #include "array.h"
  11.  
  12. static Move Killers[Constants::MaxPly];
  13.  
  14. inline void swap( Move moves[], const int i, const int j)
  15. {
  16.     Move tmp = moves[j];
  17.     moves[j] = moves[i]; 
  18.     moves[i] = tmp;
  19. }
  20.  
  21. #define SORT_LIMIT 8
  22.  
  23. int
  24. Move_Ordering::score( Board &board, const Move &move )
  25. {
  26.     int val = 0;
  27.     Square dest_square = move.DestSquare();
  28.     Square start_square = move.StartSquare();
  29.     Piece capture = board[dest_square];
  30.     if (!capture.IsEmpty())
  31.     {
  32.         ExtendedMove emove(board,move);
  33.         if (board.num_attacks(dest_square, board.OppositeSide()) == 0)
  34.         // attack on undefended piece
  35.         val += capture.Value();
  36.     else if (emove.Special() == ExtendedMove::Normal)
  37.     {
  38.             int est = attack_estimate(board,emove);
  39.         if (est > 0)
  40.            val += est;
  41.         else // losing capture
  42.            val += 40 + (est/16);
  43.     }
  44.     else // en-passant?
  45.         val += 32;
  46.     }
  47.     if (move == Killers[0])
  48.     val += 30;
  49.     ReversibleMove rmove(board, start_square, dest_square);
  50.     board.MakeMove(rmove);
  51.     val -= Scoring::positional_score(board);
  52.     if (board.CheckStatus() == Board::InCheck)
  53.        val += 25;
  54.     board.UndoMove(rmove);
  55.     return val;
  56. }
  57.  
  58. void 
  59. Move_Ordering::order_moves(Board & board,
  60.                Move moves[], const int num_moves,
  61.                const int ply, const Move & best_move)
  62. {
  63.     if (num_moves == 0)
  64.         return;
  65.     if (ply > 0)
  66.     {
  67.         // We can't afford a full sort of the moves at deeper plies.
  68.     // So we move promising moves towards the front, then sort
  69.     // the first few moves.
  70.         Array <int> scores(SORT_LIMIT);
  71.     int j = 0, i = 0;
  72.     Move tmp;
  73.      for (i = 0; i < num_moves && j < SORT_LIMIT; i++)
  74.     {
  75.         int score = 0;
  76.         const Square dest = moves[i].DestSquare();
  77.         const Square start = moves[j].StartSquare();
  78.             const Piece capture = board[dest];
  79.  
  80.         if (moves[i] == best_move)
  81.         {
  82.             swap(moves,i,0);
  83.         scores[0] = Constants::BIG;
  84.         }         
  85.         else if (!capture.IsEmpty())
  86.         {
  87.             int start_val;
  88.             if (board[start].Type() == Piece::King)
  89.                start_val = Piece::Value(Piece::Pawn);
  90.             else
  91.                start_val = board[start].Value();
  92.             int capture_val = capture.Value();
  93.                    if (Scoring::check_en_prise(board,dest,board[dest]))
  94.                // piece appears to be en prise
  95.                score = capture_val;
  96.             else if (capture_val > start_val)
  97.                score = capture_val - start_val;
  98.             else
  99.                score += 30 + (capture_val - start_val)/16;
  100.             if (moves[i] == Killers[ply])
  101.                    score += 30;
  102.  
  103.             if (i != j)
  104.             {
  105.                swap(moves,i,j);
  106.                 }
  107.             scores[j] = score;
  108.             ++j;
  109.         } 
  110.         else if (j < SORT_LIMIT)
  111.         {
  112.            // not a capture move
  113.            if (moves[i] == Killers[ply])
  114.                score += 30;
  115.            if (score)
  116.            {
  117.                scores[j] = score;
  118.                swap(moves,i,j);
  119.            ++j;
  120.            }
  121.         }
  122.     }
  123.  
  124.     if (j > 1)
  125.         sort_moves(moves,(int*)scores.get_data(),Util::Min(j,SORT_LIMIT));
  126.     } 
  127.     else 
  128.     {
  129.     // ply == 0
  130.  
  131.     Array<int> scores(num_moves);
  132.     scores[0] = 1000;    // p.v. move
  133.  
  134.     for (int i = 1; i < num_moves; i++)
  135.     {
  136.         scores[i] = score(board,moves[i]);
  137.     }
  138.     sort_moves(moves, (int*)scores.get_data(), num_moves);
  139.     }
  140. }
  141.  
  142. void 
  143. Move_Ordering::clear_killer()
  144. {
  145.     for (int i = 0; i < Constants::MaxPly; i++)
  146.     Killers[i].MakeNull();
  147. }
  148.  
  149. void 
  150. Move_Ordering::set_killer(ExtendedMove & move, const unsigned ply)
  151. {
  152.     Killers[ply] = move;
  153. }
  154.  
  155. void
  156. Move_Ordering::get_killer(Move & move, const unsigned ply)
  157. {
  158.     move = Killers[ply];
  159. }
  160.